package com.cgc.venus.server.job.jobdetail;
import com.cgc.venus.server.core.es.BaseElasticsearch;
import com.cgc.venus.server.core.utils.SpringUtil;
import com.cgc.venus.server.job.Constants;
import com.cgc.venus.server.job.config.JobConfig;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日志es服务相关处理
 */
public class EsJob extends AbstractBaseJob {
    private static Logger logger = LoggerFactory.getLogger(EsJob.class);
    public EsJob() {
    }
    public void execute(JobExecutionContext context)  
        throws JobExecutionException {
        logger.info("日志es服务相关处理 job start...");
        //  处理逻辑
        //  a. 新建索引.
        //  b. 设置分词策略.
        //  c. 设置查询最大字符集大小.
        //  d. 删除三个月之前的日志索引.
        BaseElasticsearch baseElasticsearch=SpringUtil.getBean(BaseElasticsearch.class);
        Client client=null;
        String index=null;
        try {
            client=baseElasticsearch.getEsDataSource().getClient();
                //获取明天日期
            Format f = new SimpleDateFormat("yyyy.MM.dd");
            Date today = new Date();
            Calendar c = Calendar.getInstance();
            c.setTime(today);
            c.add(Calendar.DAY_OF_MONTH, 1);// 今天+1天
            Date tomorrow = c.getTime();
            index="logstash-"+f.format(tomorrow);
            String type="fluentd";
            String mapping="{\""+type+"\":{\"properties\":{\"kubernetes\":{\"properties\":{\"namespace_name\":{\"type\":\"string\",\"index\":\"not_analyzed\"},\"pod_name\":{\"type\":\"string\",\"index\":\"not_analyzed\"}}},\"log\":{\"type\":\"string\",\"index\":\"not_analyzed\"}}}}";
            try {
                client.admin().indices().prepareCreate(index).addMapping(type,mapping).get();//创建索引并设置分词策略 a/b
                logger.info("创建索引并设置分词成功:"+index);
            }catch (Exception e){
                //logger.error(e.getMessage(),e);
                //如果该index已经存在 先删除 再创建
                client.admin().indices().prepareDelete(index).get();
                logger.info("删除已经存在的索引:"+index);
                client.admin().indices().prepareCreate(index).addMapping(type,mapping).get();//创建索引并设置分词策略 a/b
                logger.info("创建索引并设置分词成功:"+index);
            }
            client.admin().indices().prepareUpdateSettings(index).setSettings(Settings.builder().put("index.max_result_window",100000)).get();//设置查询结果集范围 默认1w 修改为10w c
            logger.info("设置索引查询结果字符集成功:"+index);
        }catch (Exception ex){
            logger.error(ex.getMessage(),ex);
            handleEx("日志es服务相关处理任务异常,异常信息:"+getErrorInfoFromException(ex),Constants.ALARM_TYPE_LOG_ES,Constants.ALARM_STATUS_UN,Constants.ALARM_LEVEL_COMMON,Constants.ALARM_NS_ALL);
        }finally {
            if(client!=null){
                 try {
                        baseElasticsearch.getEsDataSource().releaseClient(client);
                 } catch (Exception e) {
                        logger.error(e.getMessage(),e);
                 }
            }
        }

        //  d. 删除三个月之前的日志索引.
        try {
            client=baseElasticsearch.getEsDataSource().getClient();
            SearchResponse sr=client.prepareSearch("logstash*")
                    .addAggregation(
                            AggregationBuilders.terms("agg1").field("_index").size(500)
                    ).execute().actionGet();
            Terms agg1 = sr.getAggregations().get("agg1");
            List<Terms.Bucket> list=null;
            list=agg1.getBuckets();
            String text=null;
            List<String> pre_indexs=new ArrayList<>();
            for(Terms.Bucket b:list){
                text=b.getKey().toString();
                if(isDelete(text)){
                    pre_indexs.add(text);
                    logger.info("待删除索引:"+text);
                }
            }
            String[] indexs= new String[pre_indexs.size()];
            indexs=pre_indexs.toArray(indexs);
            if(indexs!=null&&indexs.length>0){
                client.admin().indices().prepareDelete(indexs).get();
                logger.info("成功删除" + indexs.length+"个索引");
            }else{
                logger.info("成功删除0个索引");
            }
        }catch (Exception ex){
            logger.error(ex.getMessage(),ex);
            handleEx("日志es服务相关处理任务异常,异常信息:"+getErrorInfoFromException(ex),Constants.ALARM_TYPE_LOG_ES,Constants.ALARM_STATUS_UN,Constants.ALARM_LEVEL_COMMON,Constants.ALARM_NS_ALL);
        }finally {
            if(client!=null){
                try {
                    baseElasticsearch.getEsDataSource().releaseClient(client);
                } catch (Exception e) {
                    logger.error(e.getMessage(),e);
                }
            }
        }
    }

    /**
     * 判断是否90天之外的数据 (将要被删除数据)
     * @param index
     * @return
     * @throws ParseException
     */
    private boolean isDelete(String index) throws ParseException {
        String date=index.split("-")[1];
        SimpleDateFormat f = new SimpleDateFormat("yyyy.MM.dd");
        Date d= f.parse(date);
        Calendar cal = Calendar.getInstance();
        JobConfig jobConfig=SpringUtil.getBean(JobConfig.class);
        cal.add(Calendar.DAY_OF_MONTH, -jobConfig.getKeepEsLogDay());
        cal.set(Calendar.HOUR_OF_DAY, 0);//小时
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        long time=cal.getTimeInMillis();
        if(time>d.getTime()){
            return true;
        }
        return false;
    }

    /**
     * 将格林威治时间字符串转换为yyyy-MM-dd HH:mm:ss字符串，JDK1.7以上版本支持该方法
     * @param s
     * @return
     */
    public static String DateString2formatString(String s)
    {
        String str="";
        try
        {
            SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
            sd.setTimeZone(TimeZone.getTimeZone("GMT+:08:00"));
            Date date=sd.parse(s);
            sdf.setTimeZone(TimeZone.getDefault());
            str=sdf.format(date);
        }
        catch(Exception e)
        {
            System.out.println(e.getMessage());
            return str;
        }
        return str;
    }

    public static void main(String[] args){
        System.out.println(DateString2formatString("2015-08-05T09:40:00+08:00"));
        //System.out.println(TimeZone.getDefault().toString());
    }
}